/*
 * 文件名： SdkPaySpdbManager.java
 * 
 * 工程名称: bis-manager
 *
 * Gopay
 *
 * 创建日期： 2017年11月9日
 *
 * Copyright(C) 2017, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.manager.bank.scan;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.dao.bankorder.BankCustAppInfoDAO;
import com.gopay.bis.dao.bankorder.BankOrderDAO;
import com.gopay.common.constants.bank.SpdbConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.CustAppInfo;
import com.gopay.common.domain.bank.spdb.agpay.PayGoodsList;
import com.gopay.common.domain.bank.spdb.agpay.QueryOrderBody;
import com.gopay.common.domain.bank.spdb.agpay.RefundBody;
import com.gopay.common.domain.bank.spdb.agpay.SdkPayBody;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.TransUtil;
import com.gopay.remote.bank.businesses.ScanPayService;

/**
 * 微信APP支付浦发银行渠道报文拼装处理
 *
 * @author 宣广海
 *
 * @version
 *
 * @since 2017年11月9日
 */
@Service("sdkPaySpdbManager")
public class SdkPaySpdbManager {

	/**
	 * 日志对象
	 */
	private static Logger logger = LoggerFactory.getLogger(SdkPaySpdbManager.class);

	@Resource(name = "agPaySpdbPayConfig")
	private Map<String, String> agPaySpdbPayConfig;

	@Resource(name = "agPaySpdbServiceClient")
	private ScanPayService agPaySpdbServiceClient;

	@Resource(name = "bankOrderDAO")
	private BankOrderDAO bankOrderDAO;

	@Resource(name = "bankCustAppInfoDAO")
	private BankCustAppInfoDAO bankCustAppInfoDAO;

	public Object payment(BaseMessage baseMsg) throws GopayException {

		baseMsg.setBankOrderId(modifyOrderId(baseMsg.getOrderId()));

		buildPaymentMchInfo(baseMsg);

		SdkPayBody body = new SdkPayBody();
		BeanUtils.copyProperties(baseMsg, body);
		PayGoodsList goodsMessage = new PayGoodsList();
		baseMsg.setBankOrderId(modifyOrderId(baseMsg.getOrderId()));
		body.setVersion(agPaySpdbPayConfig.get("SPDB.AGPAY.VERSION"));
		body.setSignType(agPaySpdbPayConfig.get("SPDB.AGPAY.SIGNTYPE"));
		body.setCharset(agPaySpdbPayConfig.get("SPDB.AGPAY.CHARSET"));
		body.setBusicd(agPaySpdbPayConfig.get("SPDB.AGPAY.SDKPAY.BUSICD"));
		body.setChcd(agPaySpdbPayConfig.get("SPDB.AGPAY.SDKPAY.CHCD"));
		body.setInscd(agPaySpdbPayConfig.get("SPDB.AGPAY.INSCD"));// 机构号
		body.setMchntid(baseMsg.getMerID());
		body.setOrderNum(baseMsg.getBankOrderId());
		body.setTxamt(TransUtil.amountConvert2Fen(String.valueOf(baseMsg.getAmount()), 12, "0"));
		body.setCurrency("CNY");

		goodsMessage.setGoodsName(body.getGoodsBody());
		goodsMessage.setPrice(TransUtil.amountConvert2Fen(String.valueOf(baseMsg.getAmount())));// 精确到分不需要补位
		goodsMessage.setGoodsNum("1");// 数量
		goodsMessage.setGoodsId(body.getGoodsBody());// 商品条码

		List<PayGoodsList> list = new ArrayList<PayGoodsList>();
		list.add(goodsMessage);
		body.setGoodsList(JSON.toJSONString(list));

		body.setOutStlmCd(body.getBank());
		body.setBackUrl(baseMsg.getPayRuturnUrl());
		body.setMchntid(baseMsg.getMerID());
		body.setSignKey(baseMsg.getPrivateKeyPath());

		BankLogUtils.printWeChatSdkManagerPaySendLog(body);
		return agPaySpdbServiceClient.payment(body);
	}

	/**
	 * 
	 * 功能描述：条码支付订单查询接口报文构建
	 *
	 * @param obj
	 * @return
	 * @throws GopayException
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年11月16日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public Object orderQuery(BaseMessage baseMsg) throws GopayException {

		QueryOrderBody message = new QueryOrderBody();
		BeanUtils.copyProperties(baseMsg, message);

		message.setVersion(agPaySpdbPayConfig.get("SPDB.AGPAY.VERSION"));
		message.setSignType(agPaySpdbPayConfig.get("SPDB.AGPAY.SIGNTYPE"));
		message.setCharset(agPaySpdbPayConfig.get("SPDB.AGPAY.CHARSET"));
		message.setTxndir("Q");// 交易方向，Q为请求，A为应答
		message.setBusicd(SpdbConstants.INQY);
		message.setInscd(agPaySpdbPayConfig.get("SPDB.AGPAY.INSCD"));// 机构号
		message.setMchntid(baseMsg.getMerID());
		message.setTerminalid(agPaySpdbPayConfig.get("SPDB.AGPAY.TERMINALID"));// 终端号

		message.setOrigOrderNum(message.getBankOrderId());// 交易订单号
		
		buildMchInfo(baseMsg);
		
		message.setMchntid(baseMsg.getMerID());
		message.setSignKey(baseMsg.getPrivateKeyPath());
		return agPaySpdbServiceClient.queryOrder(message);
	}

	/**
	 * 
	 * 功能描述：浦发退款报文构建
	 *
	 * @param obj
	 * @return
	 * @throws GopayException
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年11月16日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public Object refund(BaseMessage baseMsg) throws GopayException {

		RefundBody message = new RefundBody();
		BeanUtils.copyProperties(baseMsg, message);

		message.setVersion(agPaySpdbPayConfig.get("SPDB.AGPAY.VERSION"));
		message.setSignType(agPaySpdbPayConfig.get("SPDB.AGPAY.SIGNTYPE"));
		message.setCharset(agPaySpdbPayConfig.get("SPDB.AGPAY.CHARSET"));
		message.setTxndir("Q");// 交易方向，Q为请求，A为应答
		message.setBusicd(SpdbConstants.REFD);
		message.setInscd(agPaySpdbPayConfig.get("SPDB.AGPAY.INSCD"));// 机构号
		message.setMchntid(baseMsg.getMerID());
		message.setTerminalid(agPaySpdbPayConfig.get("SPDB.AGPAY.TERMINALID"));// 终端号

		message.setOrderNum(baseMsg.getBankOrderId());
		message.setOrigOrderNum(baseMsg.getTkOriBankOrderId());// 原交易订单号
		message.setTxamt(TransUtil.amountConvert2Fen(String.valueOf(baseMsg.getAmount()), 12, "0"));
		
		buildRefundMchInfo(baseMsg);
		
		message.setMchntid(baseMsg.getMerID());
		message.setSignKey(baseMsg.getPrivateKeyPath());
		return agPaySpdbServiceClient.refund(message);
	}
	public Object refundOrderQuery(BaseMessage baseMsg) throws GopayException {

		QueryOrderBody message = new QueryOrderBody();
		BeanUtils.copyProperties(baseMsg, message);

		message.setVersion(agPaySpdbPayConfig.get("SPDB.AGPAY.VERSION"));
		message.setSignType(agPaySpdbPayConfig.get("SPDB.AGPAY.SIGNTYPE"));
		message.setCharset(agPaySpdbPayConfig.get("SPDB.AGPAY.CHARSET"));
		message.setTxndir("Q");// 交易方向，Q为请求，A为应答
		message.setBusicd(SpdbConstants.INQY);
		message.setInscd(agPaySpdbPayConfig.get("SPDB.AGPAY.INSCD"));// 机构号
		message.setMchntid(baseMsg.getMerID());
		message.setTerminalid(agPaySpdbPayConfig.get("SPDB.AGPAY.TERMINALID"));// 终端号

		message.setOrigOrderNum(message.getBankOrderId());// 交易订单号
		
		buildRefundMchInfo(baseMsg);
		
		message.setMchntid(baseMsg.getMerID());
		message.setSignKey(baseMsg.getPrivateKeyPath());
		return agPaySpdbServiceClient.queryOrder(message);
	}
	public Object verify(BaseMessage msg) throws GopayException {
		buildMchInfo(msg);
		return agPaySpdbServiceClient.verify(msg);
	}

	/**
	 * @Description: 替换国付宝订单号前2位为SP
	 * @param orderId
	 * @return
	 * @author jxj
	 */
	private static String modifyOrderId(String orderId) {
		return "SP" + orderId.substring(2);
	}

	private BaseMessage buildPaymentMchInfo(BaseMessage baseMsg) throws GopayException {
		try {
			String interCh = baseMsg.getBankIntrChann().value;
			if (StringUtils.isNotBlank(interCh)) {
				String appId = baseMsg.getAppId();
				logger.info("appId=" + appId + ",interCh=" + interCh);
				/**
				 * 根据APPID获取商户号和商户key
				 */
				CustAppInfo custAppInfo = bankCustAppInfoDAO.getCustAppInfo(appId, interCh);
				if (null != custAppInfo) {
					baseMsg.setMchKey(custAppInfo.getMerchantKey());
					baseMsg.setMerID(custAppInfo.getMerchantId());
					baseMsg.setPrivateKeyPath(custAppInfo.getMerchantKey());
					baseMsg.setAppId(appId);
				} else {
					throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002);
				}
			} else {
				throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002);
			}
		} catch (Exception ex) {
			logger.info(ex.getMessage());
			throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002, ex);
		}
		return baseMsg;
	}

	private BaseMessage buildMchInfo(BaseMessage baseMsg) throws GopayException {
		try {
			List<BankOrder> bankOrders = bankOrderDAO.getBankOrdersByGopayOrderId(baseMsg.getOrderId());
			if (bankOrders != null && bankOrders.size() == 1) {
				String appId = bankOrders.get(0).getAppId();
				String interCh = bankOrders.get(0).getInterfaceChennelCode();
				/**
				 * 根据APPID获取商户号和商户key
				 */
				CustAppInfo custAppInfo = bankCustAppInfoDAO.getCustAppInfo(appId, interCh);
				if (null != custAppInfo) {
					baseMsg.setMchKey(custAppInfo.getMerchantKey());
					baseMsg.setMerID(custAppInfo.getMerchantId());
					baseMsg.setAppId(appId);
					baseMsg.setPrivateKeyPath(custAppInfo.getMerchantKey());
				} else {
					throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002);
				}
			} else {
				throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002);
			}
		} catch (Exception ex) {
			logger.info(ex.getMessage());
			throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002, ex);
		}
		return baseMsg;
	}

	private BaseMessage buildRefundMchInfo(BaseMessage baseMsg) throws GopayException {

		try {
			logger.info("进入退款构建报文，baseMsg.getTkOriBankOrderId()=" + baseMsg.getTkOriBankOrderId());
			BankOrder bankOrder = bankOrderDAO.find(BankOrder.class, baseMsg.getTkOriBankOrderId());

			if (bankOrder != null) {
				String appId = bankOrder.getAppId();
				String interCh = bankOrder.getInterfaceChennelCode();
				logger.info("appId=" + appId);
				/**
				 * 根据APPID获取商户号和商户key
				 */
				CustAppInfo custAppInfo = bankCustAppInfoDAO.getCustAppInfo(appId, interCh);
				if (null != custAppInfo) {
					baseMsg.setMchKey(custAppInfo.getMerchantKey());
					baseMsg.setMerID(custAppInfo.getMerchantId());
					baseMsg.setAppId(appId);
					baseMsg.setPrivateKeyPath(custAppInfo.getMerchantKey());
				} else {
					throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002);
				}
			} else {
				throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002);
			}
		} catch (Exception ex) {
			logger.info(ex.getMessage());
			throw new GopayException(ProcCodeConstants.PROC_CODE_100F1002, ex);
		}
		return baseMsg;
	}
}
